import { type ChangeEvent, type FormEvent, useEffect, useState } from 'react';
import { useMutation } from '@tanstack/react-query';
import type {
  IDifference,
  IPermissionDetails,
  IUpdatePermissionBody,
} from '@/interfaces';
import diff from 'microdiff';
import { updatePermission } from '@/services/api';
import type { TBody, TPermissionMethod, TPermissionTypeName } from '@/types';
import useToast from '@/hooks/useToast';
import { getDiffData, getFilterData, isEmpty } from '@/lib/tool';

export default function UpdatePermissionInfo({
  details,
}: {
  details: IPermissionDetails;
}) {
  const { show } = useToast();
  const [form, setForm] = useState<{
    name?: string;
    alias?: string;
    overview?: string;
    method?: TPermissionMethod;
    type?: TPermissionTypeName;
    caseInsensitive?: string;
    sort?: number;
    categoryId?: string;
    categoryName?: string;
  }>({
    name: '',
    alias: '',
    overview: '',
    method: 'GET',
    type: '路径',
    caseInsensitive: 'false',
    sort: 0,
    categoryId: '',
    categoryName: '',
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);

  const updatePermissionMutation = useMutation(
    async (variables: TBody<IUpdatePermissionBody>) => {
      await updatePermission(variables);
    },
  );

  useEffect(() => {
    if (details) {
      const { basic } = details;
      setForm({
        name: basic.name,
        alias: basic.alias || '',
        overview: basic.overview || '',
        method: basic.method,
        type: basic.type === 'ANT' ? '路径' : '正则',
        caseInsensitive: basic.caseInsensitive ? 'true' : 'false',
        sort: basic.sort,
        categoryId: basic.categoryId || '',
        categoryName: basic.categoryName || '',
      });
    }
  }, [details]);
  useEffect(() => {
    if (details) {
      const { basic } = details;
      const differences = diff(
        {
          name: basic.name,
          alias: basic.alias || '',
          overview: basic.overview || '',
          method: basic.method,
          type: basic.type === 'ANT' ? '路径' : '正则',
          caseInsensitive: basic.caseInsensitive ? 'true' : 'false',
          sort: basic.sort,
          categoryId: basic.categoryId || '',
          categoryName: basic.categoryName || '',
        },
        form,
      );
      setDifferenceData(differences);
    }
  }, [form, details]);

  function onChangeForm(
    e: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
  ) {
    const name = e.target.name;
    const value = e.target.value;

    if (name === 'caseInsensitive') {
      setForm({ ...form, caseInsensitive: value });
    } else if (name === 'sort') {
      setForm({ ...form, sort: parseInt(value) });
    } else {
      setForm({ ...form, [name]: value });
    }
  }

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      checkForm();
      const body = getFilterData(getDiffData(differenceData));
      if (isEmpty(body)) {
        show({
          type: 'SUCCESS',
          message: '保存完成',
        });
        return;
      }

      await updatePermissionMutation.mutateAsync({
        id: details.basic.id,
        data: {
          ...body,
          type: body.type === '路径' ? 'ANT' : 'REGEX',
          caseInsensitive: body.caseInsensitive === 'true',
        },
      });

      clearData();
      show({
        type: 'SUCCESS',
        message: '保存完成',
      });
    } catch (e) {
      updatePermissionMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function clearData() {
    setDifferenceData([]);
  }

  function checkForm() {
    const { name } = form;

    if (!name) {
      throw '权限名称不能为空';
    }
  }

  return (
    <div className="row">
      <div className="col">
        <form onSubmit={onClickSave} className="vstack gap-4">
          <div className="row">
            <div className="col">
              <div>
                <label className="form-label">名称</label>
                <textarea
                  className="form-control"
                  name="name"
                  value={form.name}
                  onChange={onChangeForm}
                  aria-describedby="name"
                  rows={1}
                  placeholder="请输入权限名称"
                />
              </div>
            </div>
            <div className="col">
              <div>
                <label className="form-label">别名</label>
                <input
                  type="text"
                  className="form-control"
                  name="alias"
                  value={form.alias}
                  onChange={onChangeForm}
                  aria-describedby="alias"
                  placeholder="请输入别名"
                />
              </div>
            </div>
          </div>

          <div className="row">
            <div className="col">
              <div>
                <label className="form-label">概述</label>
                <input
                  type="text"
                  className="form-control"
                  name="overview"
                  value={form.overview}
                  onChange={onChangeForm}
                  aria-describedby="overview"
                  placeholder="请输入概述"
                />
              </div>
            </div>
            <div className="col">
              <div>
                <label className="form-label">请求方法</label>
                <select
                  name="method"
                  value={form.method}
                  onChange={onChangeForm}
                  className="form-select"
                  aria-label="method"
                  placeholder="请选择请求方法"
                >
                  <option value="GET">GET</option>
                  <option value="HEAD">HEAD</option>
                  <option value="POST">POST</option>
                  <option value="PUT">PUT</option>
                  <option value="PATCH">PATCH</option>
                  <option value="DELETE">DELETE</option>
                  <option value="OPTIONS">OPTIONS</option>
                  <option value="TRACE">TRACE</option>
                </select>
              </div>
            </div>
          </div>

          <div className="row">
            <div className="col">
              <div>
                <label className="form-label">类型</label>
                <select
                  name="type"
                  value={form.type}
                  onChange={onChangeForm}
                  className="form-select"
                  aria-label="type"
                  placeholder="请选择类型"
                >
                  <option value="路径">路径</option>
                  <option value="正则">正则</option>
                </select>
              </div>
            </div>
            <div className="col">
              <div>
                <label className="form-label">大小写</label>
                <select
                  name="caseInsensitive"
                  value={form.caseInsensitive}
                  onChange={onChangeForm}
                  className="form-select"
                  aria-label="caseInsensitive"
                  placeholder="请选择是否大小写"
                >
                  <option value="false">false</option>
                  <option value="true">true</option>
                </select>
              </div>
            </div>
          </div>

          <div className="row">
            <div className="col">
              <div>
                <label className="form-label">
                  <span className="text-danger">*</span>
                  排序
                </label>
                <input
                  type="number"
                  min={0}
                  className="form-control"
                  name="sort"
                  value={form.sort}
                  onChange={onChangeForm}
                  aria-describedby="sort"
                  placeholder="请输入排序"
                />
              </div>
            </div>
            <div className="col">
              <div>
                <label className="form-label">分类 ID</label>
                <textarea
                  className="form-control"
                  name="categoryId"
                  value={form.categoryId}
                  onChange={onChangeForm}
                  aria-describedby="categoryId"
                  rows={1}
                  placeholder="请输入分类 ID"
                />
              </div>
            </div>
          </div>

          <div className="row">
            <div className="col">
              <div>
                <label className="form-label">分类名称</label>
                <input
                  type="text"
                  className="form-control"
                  name="categoryName"
                  value={form.categoryName}
                  onChange={onChangeForm}
                  aria-describedby="categoryName"
                  placeholder="请输入分类名称"
                />
              </div>
            </div>
          </div>

          <button
            type="submit"
            disabled={updatePermissionMutation.isLoading}
            className="btn btn-success w-25 my-4"
          >
            {updatePermissionMutation.isLoading && (
              <span
                className="spinner-border spinner-border-sm me-2"
                role="status"
                aria-hidden="true"
              ></span>
            )}
            更新
          </button>
        </form>
      </div>
    </div>
  );
}
